package com.choudou5.solr.util;

import cn.hutool.core.collection.CollUtil;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringEscapeUtils;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.regex.Pattern;

/**
 * @name 字符串工具类
 * @author choudou5
 * @date 2018-7-13
 */
public class StrUtil extends cn.hutool.core.util.StrUtil{


    public static String setDefVal(String str, String def) {
        return isBlank(str)?def:str;
    }

    public static String[] split(String str, String separatorChars) {
        return splitWorker(str, separatorChars, -1, false);
    }

    private static String[] splitWorker(String str, String separatorChars, int max, boolean preserveAllTokens) {
        if(str == null) {
            return null;
        } else {
            int len = str.length();
            if(len == 0) {
                return ArrayUtils.EMPTY_STRING_ARRAY;
            } else {
                ArrayList list = new ArrayList();
                int sizePlus1 = 1;
                int i = 0;
                int start = 0;
                boolean match = false;
                boolean lastMatch = false;
                if(separatorChars != null) {
                    if(separatorChars.length() != 1) {
                        label87:
                        while(true) {
                            while(true) {
                                if(i >= len) {
                                    break label87;
                                }

                                if(separatorChars.indexOf(str.charAt(i)) >= 0) {
                                    if(match || preserveAllTokens) {
                                        lastMatch = true;
                                        if(sizePlus1++ == max) {
                                            i = len;
                                            lastMatch = false;
                                        }

                                        list.add(str.substring(start, i));
                                        match = false;
                                    }

                                    ++i;
                                    start = i;
                                } else {
                                    lastMatch = false;
                                    match = true;
                                    ++i;
                                }
                            }
                        }
                    } else {
                        char sep = separatorChars.charAt(0);

                        label71:
                        while(true) {
                            while(true) {
                                if(i >= len) {
                                    break label71;
                                }

                                if(str.charAt(i) == sep) {
                                    if(match || preserveAllTokens) {
                                        lastMatch = true;
                                        if(sizePlus1++ == max) {
                                            i = len;
                                            lastMatch = false;
                                        }

                                        list.add(str.substring(start, i));
                                        match = false;
                                    }

                                    ++i;
                                    start = i;
                                } else {
                                    lastMatch = false;
                                    match = true;
                                    ++i;
                                }
                            }
                        }
                    }
                } else {
                    label103:
                    while(true) {
                        while(true) {
                            if(i >= len) {
                                break label103;
                            }

                            if(Character.isWhitespace(str.charAt(i))) {
                                if(match || preserveAllTokens) {
                                    lastMatch = true;
                                    if(sizePlus1++ == max) {
                                        i = len;
                                        lastMatch = false;
                                    }

                                    list.add(str.substring(start, i));
                                    match = false;
                                }

                                ++i;
                                start = i;
                            } else {
                                lastMatch = false;
                                match = true;
                                ++i;
                            }
                        }
                    }
                }

                if(match || preserveAllTokens && lastMatch) {
                    list.add(str.substring(start, i));
                }

                return (String[])list.toArray(new String[list.size()]);
            }
        }
    }

    public static boolean contains(String str, String searchStr) {
        if (str == null || searchStr == null) {
            return false;
        }
        return str.indexOf(searchStr) >= 0;
    }

    public static String join(Collection<Object> params, String separator) {
        if (CollUtil.isEmpty(params)) {
            return separator;
        }
        StringBuffer sb = new StringBuffer();
        int dex = 0;
        for (Object param : params) {
            sb.append((dex>0?separator:"")+param);
            dex++;
        }
        return sb.toString();
    }

    public static String removeStart(final String str, final String remove) {
        if (isEmpty(str) || isEmpty(remove)) {
            return str;
        }
        if (str.startsWith(remove)){
            return str.substring(remove.length());
        }
        return str;
    }


    public static String removeEnd(final String str, final String remove) {
        if (isEmpty(str) || isEmpty(remove)) {
            return str;
        }
        if (str.endsWith(remove)) {
            return str.substring(0, str.length() - remove.length());
        }
        return str;
    }

    public static String toSqlField(String paramName) {
        if (paramName == null)
            return null;
        return toUnderlineCase(paramName);
    }

    public static String toJavaClassName(String sqlField) {
        if (sqlField == null)
            return null;
        sqlField = toCamelCase(sqlField);
        return sqlField.substring(0, 1).toUpperCase() + sqlField.substring(1);
    }

    public static String toJavaVariableName(String str) {
        return uncapitalize(toJavaClassName(str));
    }

    public static String uncapitalize(String str) {
        return changeFirstCharacterCase(str, false);
    }

    private static String changeFirstCharacterCase(String str, boolean capitalize) {
        if (str == null || str.length() == 0) {
            return str;
        }
        StringBuffer buf = new StringBuffer(str.length());
        if (capitalize) {
            buf.append(Character.toUpperCase(str.charAt(0)));
        }
        else {
            buf.append(Character.toLowerCase(str.charAt(0)));
        }
        buf.append(str.substring(1));
        return buf.toString();
    }

    public static String[] toStringArray(Enumeration<String> enumeration) {
        if(enumeration == null) {
            return null;
        } else {
            ArrayList list = Collections.list(enumeration);
            return (String[])list.toArray(new String[list.size()]);
        }
    }

    public static String abbrText(String text, int sub) {
        if(isBlank(text))
            return "";
        String append = "";
        int len = text.length();
        if(len < sub){
            sub = len;
        }else{
            append = "...";
        }
        return sub(text, 0, sub) + append;
    }

    private static Pattern mailPattern = Pattern.compile("^^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,6}$");

    public static boolean isEmail(String text) {
        if(isBlank(text))
            return false;
        return mailPattern.matcher(text).matches();
    }

    public static String encode(String text, String chartset) {
        try {
            return URLEncoder.encode(text,chartset);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String decode(String text, String chartset) {
        try {
            return URLDecoder.decode(text, chartset);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 是否为 UTF8 编码
     * @param str
     */
    public static boolean isUTF8(String str) {
        char[] chars =str.toCharArray();
        for (char c : chars) {
            if((int)c == 65533)
                return false;
        }
        return true;
    }


    public static String asciiToStr(byte[] bytes){
        StringBuffer sbu = new StringBuffer();
        for (int i = 0; i < bytes.length; i++) {
            sbu.append((char)bytes[i]);
        }
        return sbu.toString();
    }

    public static void main(String[] args) throws Exception{
//        System.out.println(toJavaClassName("hello_world"));
//        System.out.println(toUnderlineCase("HelloWorld"));
//        System.out.println(toUnderlineCase("createTime"));
//        System.out.println(toJavaVariableName("hello_world"));
//        System.out.println(isEmail("xx@sina.cn"));
//        System.out.println(isUTF8("xx@sina.cn"));

        System.out.println(isUTF8("���"));
        System.out.println(isUTF8("ç®\u0097å\u0091½"));
        System.out.println(StringEscapeUtils.unescapeJava("ç®\u0097å\u0091½"));


        System.out.println(new String("算命".getBytes("ISO-8859-1") , "utf-8"));

        System.out.println(StringEscapeUtils.escapeJava("121sdç®f4#算命"));

        System.out.println(StringEscapeUtils.unescapeJava("阿斯蒂芬$%sws"));

    }

}
